<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="shortcut icon" href="">
    <title>maze</title>
    <style type="text/css">
        body {
            background-color: #eccc68;
        }

        canvas {
            width: 400px;
            height: 300px;
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <script type="module">
        import {createCanvas, vector2, animation, mouse, curve, circle, rect, line, fill, stroke, frame} from './spring/board.js'
        import {Particle, Spring} from './spring/object.js'

        const width = 1200, height = 800, w = 50
        const cols = ~~(width / w), rows = ~~(height / w)
        function index(i, j) {
            if (i < 0 || j < 0 || i > cols - 1 || j > rows - 1) return -1
            return i + j * cols
        }
        class Cell {
            constructor(i, j) {
                this.i = i
                this.j = j
                this.walls = [true, true, true, true]
            }

            update(dt=1) {

            }

            checkNeigbors() {
                let neigbors = []
                let top    = grid[index(this.i    , this.j - 1)]
                let right  = grid[index(this.i + 1, this.j)]
                let bottom = grid[index(this.i    , this.j + 1)]
                let left   = grid[index(this.i - 1, this.j)]

                if (top && !top.visited) {
                    neigbors.push(top)
                }
                if (right && !right.visited) {
                    neigbors.push(right)
                }
                if (bottom && !bottom.visited) {
                    neigbors.push(bottom)
                }
                if (left && !left.visited) {
                    neigbors.push(left)
                }
                if (neigbors.length > 0) {
                    let r = ~~(Math.random() * neigbors.length)
                    return neigbors[r]
                }
                return undefined
            }

            heightLight() {
                rect((this.i + 0.5) * w, (this.j + 0.5) * w, w, w)
                fill('#ff634811')
            }

            show() {
                for (let i = 0; i < 4; ++i) {
                    if (!this.walls[i]) continue
                    let x = this.i * w, y = this.j * w
                    i === 0 && line(x    , y    , x + w, y) // 0
                    i === 1 && line(x + w, y    , x + w, y + w) // 1
                    i === 2 && line(x    , y + w, x + w, y + w) // 2
                    i === 3 && line(x    , y    , x    , y + w) // 3
                    stroke('#000', 2)
                }

                if (this.visited) {
                    rect((this.i + 0.5) * w + 0.5, (this.j + 0.5) * w + 0.5, w - 1, w - 1)
                    fill('#7bed9f')
                }
            }
        }
        /**
         * 破墙
         */
        function removeWall(a, b) {
            let x = a.i - b.i
            if (x === 1) {
                a.walls[3] = false
                b.walls[1] = false
            } else if (x === -1) {
                a.walls[1] = false
                b.walls[3] = false
            }

            let y = a.j - b.j
            if (y === 1) {
                a.walls[0] = false
                b.walls[2] = false
            } else if (y === -1) {
                a.walls[2] = false
                b.walls[0] = false
            }
        }

        const grid = [], stack = []
        for (let j = 0; j < rows; ++j) {
            for (let i = 0; i < cols; ++i) {
                grid.push(new Cell(i, j))
            }
        }

        let current = grid[0]
        createCanvas(600, 400)
        frame(10)
        function draw() {
            grid.forEach(cell => {
                cell.show()
            })

            current.visited = true
            current.heightLight()
            // 选中下一方块
            let next = current.checkNeigbors()
            if (next) {
                // 入栈
                stack.push(current)
                // 连通当前方块与下一方块
                removeWall(current, next)
                // 跳到下一方块
                current = next
            } else if (stack.length > 0) {
                // 出栈
                current = stack.pop()
            }
        }
        animation(draw)
    </script>
</body>

</html>